﻿/**
 * @file std_vector.c
 * Copyright (c) 2019 Gaaagaa. All rights reserved.
 * 
 * @author  : Gaaagaa
 * @date    : 2019-09-09
 * @version : 1.0.0.0
 * @brief   : 使用 C API 的接口形式实现 向量 容器。
 */

/**
 * The MIT License (MIT)
 * Copyright (c) Gaaagaa. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "std_vector.h"
#include "std_debug.h"
#include "std_vector.inl"

////////////////////////////////////////////////////////////////////////////////

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif // __GNUC__

////////////////////////////////////////////////////////////////////////////////

//====================================================================

// 
// xstd_vector_t 的内部相关操作接口
// 

/**********************************************************/
/**
 * @brief 清空整个 xstd_vector_t 对象，同时释放缓存。
 */
static xvct_void_t vector_cleanup(xvct_this_t xvct_this)
{
    xvct_iter_t xiter_trav = XVCT_ITER_BEGIN(xvct_this);

    if (XVCT_NULL == xiter_trav)
    {
        return;
    }

    while (xiter_trav != XVCT_ITER_END(xvct_this))
    {
        XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
        XVCT_ITER_NEXT(xvct_this, xiter_trav);
    }

    XVCT_DEALLOC(xvct_this, XVCT_ITER_HEAD(xvct_this));
    XVCT_RESET_ENTRY(xvct_this);
}

/**********************************************************/
/**
 * @brief 
 * 将 xstd_vector 对象内指定区间 [ xiter_first, xiter_last ) 
 * 转移至 [ xiter_dest, xiter_dest + (xiter_last - xiter_first) ) 位置上。
 * 
 * @param [in,out] xvct_this   : xstd_vector 对象。
 * @param [in    ] xiter_dest  : 后移操作的目标位置。
 * @param [in    ] xiter_first : 所操作区间的起始位置。
 * @param [in    ] xiter_last  : 所操作区间的结束位置。
 */
static xvct_void_t vector_move(
                    xvct_this_t xvct_this,
                    xvct_iter_t xiter_dest,
                    xvct_iter_t xiter_first,
                    xvct_iter_t xiter_last)
{
    if (xiter_dest < xiter_first)
    {
        while (xiter_first != xiter_last)
        {
            XVCT_ALMOVE(
                xvct_this,
                XVCT_ITER_ELEM(xiter_dest),
                XVCT_ITER_ELEM(xiter_first));

            XVCT_ITER_NEXT(xvct_this, xiter_dest );
            XVCT_ITER_NEXT(xvct_this, xiter_first);
        }
    }
    else if (xiter_dest > xiter_first) // ignore (xiter_dest == xiter_first)
    {
        XVCT_ITER_SEEK(
            xvct_this,
            xiter_dest,
            XVCT_ITER_DIST(xvct_this, xiter_first, xiter_last));

        while (xiter_first != xiter_last)
        {
            XVCT_ITER_PREV(xvct_this, xiter_dest);
            XVCT_ITER_PREV(xvct_this, xiter_last);

            XVCT_ALMOVE(
                xvct_this,
                XVCT_ITER_ELEM(xiter_dest),
                XVCT_ITER_ELEM(xiter_last));
        }
    }
}

/**********************************************************/
/**
 * @brief 
 * 依据给出的 xstd_vector_t 对象要容纳的有效节点数量，
 * 计算出适合当前存储缓存的最大节点容量。
 */
static xvct_size_t vector_calc_capacity(
                        xvct_this_t xvct_this,
                        xvct_size_t xst_csize)
{
    if (xst_csize <= 8)
    {
        xst_csize = 8;
    }
    else
    {
        xst_csize = std_ceil2pow(xst_csize);
        if (xst_csize > XVCT_MAX_SIZE(xvct_this))
            xst_csize = XVCT_MAX_SIZE(xvct_this);
    }

    return xst_csize;
}

/**********************************************************/
/**
 * @brief 修改 xstd_vector_t 对象的当前容量。
 * @note  新设定的容量 xst_csize 值，不可小于当前有效节点数量。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xst_csize : 新设定的容量。
 */
static xvct_void_t vector_modify_capacity(
                        xvct_this_t xvct_this,
                        xvct_size_t xst_csize)
{
    XASSERT((0 != xst_csize) && (xst_csize >= XVCT_SIZE(xvct_this)));

    xvct_size_t xvct_size = XVCT_SIZE(xvct_this);
    xvct_iter_t xvct_iter = XVCT_NULL;

    xst_csize = vector_calc_capacity(xvct_this, xst_csize);
    xvct_iter = (xvct_iter_t)XVCT_MALLOC(
        xvct_this, xst_csize * XVCT_ESIZE(xvct_this));
    XASSERT(XVCT_NULL != xvct_iter);

    if (XVCT_NULL != XVCT_ITER_HEAD(xvct_this))
    {
        vector_move(
            xvct_this,
            xvct_iter,
            XVCT_ITER_BEGIN(xvct_this),
            XVCT_ITER_END(xvct_this));

        XVCT_DEALLOC(xvct_this, XVCT_ITER_HEAD(xvct_this));
    }

    XVCT_ITER_HEAD(xvct_this) = xvct_iter;
    XVCT_ITER_END(xvct_this)  = XVCT_ITER_OFFS(xvct_this, xvct_iter, xvct_size);
    XVCT_ITER_TAIL(xvct_this) = XVCT_ITER_OFFS(xvct_this, xvct_iter, xst_csize);
}

/**********************************************************/
/**
 * @brief 对 xstd_vector_t 对象进行扩容操作。
 * @note 
 * 若当前的容量，依然能满足扩充需求，
 * 即 ((已存储的节点数量 + 扩充节点数量) <= 最大节点容量)，
 * 则取消扩容操作。
 * 
 * @param [in ] xvct_this : xstd_vector_t 对象。
 * @param [in ] xst_gsize : 扩充可容纳的节点数量。
 */
static xvct_void_t vector_expand(
                        xvct_this_t xvct_this,
                        xvct_size_t xst_gsize)
{
    xst_gsize += XVCT_SIZE(xvct_this);
    if (xst_gsize > XVCT_CAPACITY(xvct_this))
    {
        vector_modify_capacity(xvct_this, xst_gsize);
    }
}

/**********************************************************/
/**
 * @brief 
 * 收缩 xstd_vector_t 对象的缓存。
 * @note 
 * 当缓存 有效节点数量 低于 最大节点数容量 的半数 时，
 * 调用该接口可释放多余的缓存空间。
 */
static xvct_void_t vector_shrink(xvct_this_t xvct_this)
{
    xvct_size_t xst_csize = XVCT_SIZE(xvct_this);

    if (0 == xst_csize)
    {
        XVCT_DEALLOC(xvct_this, XVCT_ITER_HEAD(xvct_this));
        XVCT_RESET_ENTRY(xvct_this);
    }
    else if (xst_csize <= (XVCT_CAPACITY(xvct_this) >> 1))
    {
        vector_modify_capacity(xvct_this, xst_csize);
    }
}

/**********************************************************/
/**
 * @brief 向 xstd_vector_t 对象末端附加多个同值元素的节点。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xst_count : 附加节点的数量。
 * @param [in    ] xvct_elem : 附加的元素值。
 */
static xvct_void_t vector_append(
                        xvct_this_t xvct_this,
                        xvct_size_t xst_count,
                        xvct_elem_t xvct_elem)
{
    XASSERT((XVCT_SIZE(xvct_this) + xst_count) <= XVCT_CAPACITY(xvct_this));

    xvct_iter_t xiter_trav = XVCT_ITER_END(xvct_this);

    while (xst_count-- > 0)
    {
        XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(xiter_trav), xvct_elem);
        XVCT_ITER_NEXT(xvct_this, xiter_trav);
    }

    XVCT_ITER_END(xvct_this) = xiter_trav;
}

/**********************************************************/
/**
 * @brief 
 * 删除 xstd_vector_t 对象指定区域 [ xiter_first, xiter_last ) 的节点。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_first : 删除区域的起始节点位置。
 * @param [in    ] xiter_last  : 删除区域的结束节点位置。
 */
static xvct_void_t vector_append_range(
                        xvct_this_t xvct_this,
                        xvct_iter_t xiter_first,
                        xvct_iter_t xiter_last)
{
    XASSERT(XVCT_ITER_DIST(xvct_this, xiter_first, xiter_last) <= XVCT_REMAIN(xvct_this));

    xvct_iter_t xiter_trav = XVCT_ITER_END(xvct_this);

    while (xiter_first != xiter_last)
    {
        XVCT_ALFROM(
            xvct_this, XVCT_ITER_ELEM(xiter_trav), XVCT_ITER_ELEM(xiter_first));
        XVCT_ITER_NEXT(xvct_this, xiter_trav );
        XVCT_ITER_NEXT(xvct_this, xiter_first);
    }

    XVCT_ITER_END(xvct_this) = xiter_trav;
}

/**********************************************************/
/**
 * @brief 
 * 删除 xstd_vector_t 对象指定区域 [ xiter_first, xiter_last ) 的节点。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_first : 删除区域的起始节点位置。
 * @param [in    ] xiter_last  : 删除区域的结束节点位置。
 */
static xvct_void_t vector_erase_range(
                        xvct_this_t xvct_this,
                        xvct_iter_t xiter_first,
                        xvct_iter_t xiter_last)
{
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_first));
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_last));
    XASSERT(xiter_first <= xiter_last);

    xvct_iter_t xiter_trav = xiter_first;
    xvct_size_t xst_rgsize = XVCT_ITER_DIST(xvct_this, xiter_first, xiter_last);

    while (xiter_trav != xiter_last)
    {
        XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
        XVCT_ITER_NEXT(xvct_this, xiter_trav);
    }

    vector_move(
        xvct_this,
        xiter_first,
        xiter_trav,
        XVCT_ITER_END(xvct_this));

    XVCT_ITER_SEEK(xvct_this, XVCT_ITER_END(xvct_this), -(xvct_ssize_t)xst_rgsize);
}

/**********************************************************/
/**
 * @brief 
 * 使 xstd_vector_t 对象的指定区段 [ xiter_pos, xiter_pos + xst_count )
 * 空闲出来，用于存储新的节点元素。
 * 
 * @param [in ] xvct_this : xstd_vector_t 对象。
 * @param [in ] xiter_pos : 所操作的区段起始位置。
 * @param [in ] xst_count : 所操作的区段大小（节点数量）。
 * 
 * @return xvct_iter_t : 
 * 返回 空闲出来的区段的起始位置，即原 xiter_pos 对应的节点位置。
 */
static xvct_iter_t vector_unoccupy(
                        xvct_this_t xvct_this,
                        xvct_iter_t xiter_pos,
                        xvct_size_t xst_count)
{
    xvct_iter_t xvct_iter = XVCT_NULL;
    xvct_size_t xst_rsize = XVCT_SIZE(xvct_this) + xst_count;
    xvct_size_t xst_csize = 0;
    xvct_size_t xst_dsize = 0;

    //======================================

    if (xst_rsize <= XVCT_CAPACITY(xvct_this))
    {
        vector_move(
            xvct_this,
            XVCT_ITER_OFFS(xvct_this, xiter_pos, xst_count),
            xiter_pos,
            XVCT_ITER_END(xvct_this));

        XVCT_ITER_SEEK(xvct_this, XVCT_ITER_END(xvct_this), xst_count);
        return xiter_pos;
    }

    //======================================

    xst_csize = vector_calc_capacity(xvct_this, xst_rsize);
    xvct_iter = (xvct_iter_t)XVCT_MALLOC(
        xvct_this, xst_csize * XVCT_ESIZE(xvct_this));
    XASSERT(XVCT_NULL != xvct_iter);

    //======================================

    if (XVCT_ITER_END(xvct_this) == xiter_pos)
    {
        vector_move(
            xvct_this,
            xvct_iter,
            XVCT_ITER_BEGIN(xvct_this),
            XVCT_ITER_END(xvct_this));
    }
    else
    {
        // the part of left
        vector_move(
            xvct_this,
            xvct_iter,
            XVCT_ITER_BEGIN(xvct_this),
            xiter_pos);

        // the part of right
        xst_dsize = XVCT_ITER_DIST(xvct_this, XVCT_ITER_BEGIN(xvct_this), xiter_pos);
        vector_move(
            xvct_this,
            XVCT_ITER_OFFS(xvct_this, xvct_iter, xst_dsize + xst_count),
            xiter_pos,
            XVCT_ITER_END(xvct_this));
    }

    //======================================

    if (XVCT_NULL != XVCT_ITER_HEAD(xvct_this))
    {
        XVCT_DEALLOC(xvct_this, XVCT_ITER_HEAD(xvct_this));
    }

    XVCT_ITER_HEAD(xvct_this) = xvct_iter;
    XVCT_ITER_END(xvct_this)  = XVCT_ITER_OFFS(xvct_this, xvct_iter, xst_rsize);
    XVCT_ITER_TAIL(xvct_this) = XVCT_ITER_OFFS(xvct_this, xvct_iter, xst_csize);

    xiter_pos = XVCT_ITER_OFFS(xvct_this, xvct_iter, xst_dsize);

    //======================================

    return xiter_pos;
}

/**********************************************************/
/**
 * @brief 对区间 [ xiter_first, xiter_last ) 进行 插入排序（insertion sort）。
 * 
 * @param [in ] xvct_this   : xstd_vector_t 对象。
 * @param [in ] xiter_first : 所排序区间的起始位置。
 * @param [in ] xiter_last  : 所排序区间的结束位置。
 * @param [in ] xfunc_fcmp  : 排序操作使用的比较函数。
 * 
 * @return xvct_iter_t : 返回结束位置的迭代器 xiter_last 。
 *         
 */
static xvct_iter_t vector_isort(
                        xvct_this_t xvct_this,
                        xvct_iter_t xiter_first,
                        xvct_iter_t xiter_last,
                        xvct_fcmp_t xfunc_fcmp)
{
    xvct_iter_t xiter_trav = XVCT_NULL;
    xvct_iter_t xiter_hole = XVCT_NULL;
    xvct_iter_t xiter_back = XVCT_NULL;
    xvct_iter_t xiter_swap = XVCT_NULL;

    if (xiter_first == xiter_last)
    {
        return xiter_last;
    }

    xiter_swap = (xvct_iter_t)XVCT_MALLOC(xvct_this, XVCT_ESIZE(xvct_this));
    XASSERT(XVCT_NULL != xiter_swap);

    for (xiter_trav = xiter_first; XVCT_ITER_NEXT(xvct_this, xiter_trav) != xiter_last; )
    {
        // order next element
        xiter_hole = xiter_trav;
        xiter_back = xiter_trav;
        XVCT_ALMOVE(
            xvct_this,
            XVCT_ITER_ELEM(xiter_swap),
            XVCT_ITER_ELEM(xiter_trav));

        if (xfunc_fcmp(
                XVCT_ITER_ELEM(xiter_swap),
                XVCT_ITER_ELEM(xiter_first),
                XVCT_ECTXT(xvct_this)))
        {
            while (xiter_first != XVCT_ITER_PREV(xvct_this, xiter_back))
            {
                XVCT_ALMOVE(
                    xvct_this,
                    XVCT_ITER_ELEM(xiter_hole),
                    XVCT_ITER_ELEM(xiter_back));
                XVCT_ITER_PREV(xvct_this, xiter_hole);
            }

            XVCT_ALMOVE(
                xvct_this,
                XVCT_ITER_ELEM(xiter_first),
                XVCT_ITER_ELEM(xiter_swap));
        }
        else
        {
            // look for insertion point after first
            while (xfunc_fcmp(
                        XVCT_ITER_ELEM(xiter_swap),
                        XVCT_ITER_ELEM(XVCT_ITER_PREV(xvct_this, xiter_back)),
                        XVCT_ECTXT(xvct_this)))
            {
                // move hole down
                XVCT_ALMOVE(
                    xvct_this,
                    XVCT_ITER_ELEM(xiter_hole),
                    XVCT_ITER_ELEM(xiter_back));
                xiter_hole = xiter_back;
            }

            // insert element in hole
            XVCT_ALMOVE(
                xvct_this,
                XVCT_ITER_ELEM(xiter_hole),
                XVCT_ITER_ELEM(xiter_swap));
        }
    }

    XVCT_DEALLOC(xvct_this, xiter_swap);

    return xiter_last;
}

//====================================================================

// 
// xstd_vector_t 的外部相关操作接口
// 

/**********************************************************/
/**
 * @brief 返回内部的 sizeof(xstd_vector_t) 值。
 */
xvct_size_t std_vector_sizeof(void)
{
    return (xvct_size_t)sizeof(xstd_vector_t);
}

/**********************************************************/
/**
 * @brief 创建 xstd_vector_t 对象。
 * @note  销毁该接口所返回的对象时，用 @see std_vector_destroy() 实现。
 * 
 * @param [in ] xvct_ctxt : 向量 所存储的节点元素上下文描述信息。
 * 
 * @return xvct_this_t : 返回所创建 xstd_vector_t 对象指针。
 */
xvct_this_t std_vector_create(xvct_ctxt_t xvct_ctxt)
{
    XASSERT(XVCT_NULL != xvct_ctxt);
    XASSERT(0 != xvct_ctxt->xstd_etype);
    XASSERT(0 != xvct_ctxt->xstd_esize);

    xstd_altor_t xstd_altor = XSTD_ALTOR_NCREF(xvct_ctxt->xstd_altor);
    xvct_this_t xvct_this = 
        (xvct_this_t)xstd_altor->xfunc_allocate(sizeof(xstd_vector_t));
    XASSERT(XVCT_NULL != xvct_this);

    return std_vector_emplace_create(xvct_this, xvct_ctxt);
}

/**********************************************************/
/**
 * @brief 销毁 xstd_vector_t 对象，其由 @see std_vector_create() 所创建。
 */
xvct_void_t std_vector_destroy(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);

    xstd_altor_t xstd_altor = XVCT_ALTOR(xvct_this);

    std_vector_emplace_destroy(xvct_this);
    xstd_altor->xfunc_dealloc(xvct_this);
}

/**********************************************************/
/**
 * @brief 在指定缓存上创建 xstd_vector_t 对象。
 * @note 
 * 1. 所指定的缓存，其大小不可小于 @see std_vector_sizeof() 的返回值。
 * 2. 销毁该接口所返回的对象时，用 @see std_vector_emplace_destroy() 实现。
 * 
 * @param [in,out] xvct_this : 创建 xstd_vector_t 对象所使用的缓存。
 * @param [in    ] xvct_ctxt : 向量 所存储的节点元素上下文描述信息。
 * 
 * @return xvct_this_t : 返回所创建 xstd_vector_t 对象指针。
 */
xvct_this_t std_vector_emplace_create(
                xvct_this_t xvct_this,
                xvct_ctxt_t xvct_ctxt)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_NULL != xvct_ctxt);
    XASSERT(0 != xvct_ctxt->xstd_etype);
    XASSERT(0 != xvct_ctxt->xstd_esize);

    //======================================

    XVCT_ECTXT_UPDATE(xvct_this, xvct_ctxt);
    XVCT_RESET_ENTRY(xvct_this);

    //======================================

    return xvct_this;
}

/**********************************************************/
/**
 * @brief 
 * 销毁指定缓存上的 xstd_vector_t 对象，
 * 其由 @see std_vector_emplace_create() 所创建。
 */
xvct_void_t std_vector_emplace_destroy(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    vector_cleanup(xvct_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的 上下文信息。
 */
xvct_ctxt_t std_vector_ctxt(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_ECTXT(xvct_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的 类型标识。
 */
xvct_size_t std_vector_etype(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_ETYPE(xvct_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象所存储的节点元素数量。
 */
xvct_size_t std_vector_size(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_SIZE(xvct_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象当前的节点元素容量。
 */
xvct_size_t std_vector_capacity(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_CAPACITY(xvct_this);
}

/**********************************************************/
/**
 * @brief 判断 xstd_vector_t 对象是否为空。
 */
xvct_bool_t std_vector_empty(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_EMPTY(xvct_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象可容纳节点元素的最大数量。
 */
xvct_size_t std_vector_maxsize(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_MAX_SIZE(xvct_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象存储节点元素的数组缓存地址。
 */
xvct_elem_t std_vector_data(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_ITER_ELEM(XVCT_ITER_BEGIN(xvct_this));
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象指定索引位置上的 元素。
 * 
 * @param [in ] xvct_this : xstd_vector_t 对象。
 * @param [in ] xvct_vpos : 索引位置。
 * 
 * @return xvct_elem_t : 所存储的元素对象。
 */
xvct_elem_t std_vector_at(xvct_this_t xvct_this, xvct_size_t xvct_vpos)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(xvct_vpos < XVCT_SIZE(xvct_this));

    return XVCT_ITER_ELEM(
        XVCT_ITER_OFFS(xvct_this, XVCT_ITER_BEGIN(xvct_this), xvct_vpos));
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的前端节点元素。
 */
xvct_elem_t std_vector_front(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(!XVCT_EMPTY(xvct_this));
    return XVCT_ITER_ELEM(XVCT_ITER_BEGIN(xvct_this));
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的后端节点元素。
 */
xvct_elem_t std_vector_back(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(!XVCT_EMPTY(xvct_this));
    return XVCT_ITER_ELEM(XVCT_ITER_RBEGIN(xvct_this));
}

/**********************************************************/
/**
 * @brief 将一定数量的特定元素值 指派给 xstd_vector_t 对象。
 * @note 
 * 1. 操作完成后，容器的节点数量为指定的 xvct_size 值。
 * 2. 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xvct_size : 指派元素的数量。
 * @param [in    ] xvct_elem : 指派的元素值。
 */
xvct_void_t std_vector_assign(
                xvct_this_t xvct_this,
                xvct_size_t xvct_size,
                xvct_elem_t xvct_elem)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(xvct_size <= XVCT_MAX_SIZE(xvct_this));
    XASSERT((0 == xvct_size) || (XVCT_NULL != xvct_elem));

    xvct_size_t xvct_csize = 0;
    xvct_iter_t xiter_trav = XVCT_NULL;

    if (xvct_size > XVCT_CAPACITY(xvct_this))
    {
        vector_cleanup(xvct_this);
        vector_modify_capacity(xvct_this, xvct_size);
        vector_append(xvct_this, xvct_size, xvct_elem);

        return;
    }

    xvct_csize = XVCT_SIZE(xvct_this);
    xiter_trav = XVCT_ITER_BEGIN(xvct_this);

#if 0
    for (;;)
    {
        if (xiter_trav == XLIST_END(xvct_this))
        {
            vector_append(xvct_this, xvct_size, xvct_elem);
            break;
        }

        if (0 == xvct_size)
        {
            vector_erase_range(xvct_this, xiter_trav, XVCT_ITER_END(xvct_this));
            break;
        }

        XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
        XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(xiter_trav), xvct_elem);
        XVCT_ITER_NEXT(xvct_this, xiter_trav);
        --xvct_size;
    }
#else
    if (xvct_size == xvct_csize)
    {
        while (xiter_trav != XVCT_ITER_END(xvct_this))
        {
            XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
            XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(xiter_trav), xvct_elem);
            XVCT_ITER_NEXT(xvct_this, xiter_trav);
        }
    }
    else if (xvct_size > xvct_csize)
    {
        while (xiter_trav != XVCT_ITER_END(xvct_this))
        {
            XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
            XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(xiter_trav), xvct_elem);
            XVCT_ITER_NEXT(xvct_this, xiter_trav);
        }

        vector_append(xvct_this, xvct_size - xvct_csize, xvct_elem);
    }
    else
    {
        for (; xvct_size > 0; --xvct_size)
        {
            XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
            XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(xiter_trav), xvct_elem);
            XVCT_ITER_NEXT(xvct_this, xiter_trav);
        }

        vector_erase_range(xvct_this, xiter_trav, XVCT_ITER_END(xvct_this));
    }
#endif
}

/**********************************************************/
/**
 * @brief 
 * 将一组元素 [ xiter_first, xiter_last ) 指派给 xstd_vector_t 对象。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_first : 指派的元素数组起始地址。
 * @param [in    ] xiter_last  : 指派的元素数组结束地址。
 */
xvct_void_t std_vector_assign_array(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_first,
                xvct_iter_t xiter_last)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_NULL != xiter_first);
    XASSERT(XVCT_NULL != xiter_last);
    XASSERT(xiter_first <= xiter_last);
    XASSERT(XVCT_ITER_OUTER(xvct_this, xiter_first));
    XASSERT(XVCT_ITER_OUTER(xvct_this, xiter_last));

    xvct_size_t xvct_csize = 0;
    xvct_iter_t xiter_trav = XVCT_NULL;
    xvct_size_t xst_acount = XVCT_ITER_DIST(xvct_this, xiter_first, xiter_last);

    if (xst_acount > XVCT_CAPACITY(xvct_this))
    {
        vector_cleanup(xvct_this);
        vector_modify_capacity(xvct_this, xst_acount);
        vector_append_range(xvct_this, xiter_first, xiter_last);

        return;
    }

    xvct_csize = XVCT_SIZE(xvct_this);
    xiter_trav = XVCT_ITER_BEGIN(xvct_this);

#if 0
    for (;;)
    {
        if (xiter_trav == XLIST_END(xvct_this))
        {
            vector_append_range(xvct_this, xiter_first, xiter_last);
            break;
        }

        if (xiter_first == xiter_last)
        {
            vector_erase_range(xvct_this, xiter_trav, XVCT_ITER_END(xvct_this));
            break;
        }

        XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
        XVCT_ALFROM(
            xvct_this, XVCT_ITER_ELEM(xiter_trav), XVCT_ITER_ELEM(xiter_first));

        XVCT_ITER_NEXT(xvct_this, xiter_trav );
        XVCT_ITER_NEXT(xvct_this, xiter_first);
    }
#else
    if (xst_acount == xvct_csize)
    {
        while (xiter_trav != XVCT_ITER_END(xvct_this))
        {
            XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
            XVCT_ALFROM(
                xvct_this,
                XVCT_ITER_ELEM(xiter_trav),
                XVCT_ITER_ELEM(xiter_first));

            XVCT_ITER_NEXT(xvct_this, xiter_trav );
            XVCT_ITER_NEXT(xvct_this, xiter_first);
        }
    }
    else if (xst_acount > xvct_csize)
    {
        while (xiter_trav != XVCT_ITER_END(xvct_this))
        {
            XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
            XVCT_ALFROM(
                xvct_this,
                XVCT_ITER_ELEM(xiter_trav),
                XVCT_ITER_ELEM(xiter_first));

            XVCT_ITER_NEXT(xvct_this, xiter_trav );
            XVCT_ITER_NEXT(xvct_this, xiter_first);
        }

        vector_append_range(xvct_this, xiter_first, xiter_last);
    }
    else
    {
        while (xiter_first != xiter_last)
        {
            XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
            XVCT_ALFROM(
                xvct_this,
                XVCT_ITER_ELEM(xiter_trav),
                XVCT_ITER_ELEM(xiter_first));

            XVCT_ITER_NEXT(xvct_this, xiter_trav );
            XVCT_ITER_NEXT(xvct_this, xiter_first);
        }

        vector_erase_range(xvct_this, xiter_trav, XVCT_ITER_END(xvct_this));
    }
#endif
}

/**********************************************************/
/**
 * @brief 使用指定元素值填充 xstd_vector_t 对象指定区域的节点元素。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_first : 填充操作的区域起始节点位置。
 * @param [in    ] xiter_last  : 填充操作的区域结束节点位置。
 * @param [in    ] xvct_elem   : 填充操作所使用的。
 */
xvct_void_t std_vector_fill(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_first,
                xvct_iter_t xiter_last,
                xvct_elem_t xvct_elem)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_first));
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_last));
    XASSERT(xiter_first <= xiter_last);
    XASSERT(XVCT_NULL != xvct_elem);

    xvct_iter_t xiter_trav = xiter_first;

    while (xiter_trav != xiter_last)
    {
        XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_trav));
        XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(xiter_trav), xvct_elem);
        XVCT_ITER_NEXT(xvct_this, xiter_trav);
    }
}

/**********************************************************/
/**
 * @brief 
 * 调整 xstd_vector_t 对象的内部存储缓存大小，
 * 释放多余空间，以适应当前容纳的节点元素数量。
 */
xvct_void_t std_vector_shrink(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    vector_shrink(xvct_this);
}

/**********************************************************/
/**
 * @brief 清空 xstd_vector_t 对象所有存储的节点元素。
 */
xvct_void_t std_vector_clear(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    vector_erase_range(
        xvct_this, XVCT_ITER_BEGIN(xvct_this), XVCT_ITER_END(xvct_this));
}

/**********************************************************/
/**
 * @brief 
 * 在 xstd_vector_t 对象指定位置上插入元素。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xiter_pos : 插入节点的位置。
 * @param [in    ] xvct_elem : 节点所存储的元素。
 * 
 * @return xvct_iter_t : 插入后的节点对应的迭代器位置。
 */
xvct_iter_t std_vector_insert(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos,
                xvct_elem_t xvct_elem)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_pos));
    XASSERT(XVCT_NULL != xvct_elem);

    xiter_pos = vector_unoccupy(xvct_this, xiter_pos, 1);

    XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(xiter_pos), xvct_elem);

    return xiter_pos;
}

/**********************************************************/
/**
 * @brief 
 * 以右值 move 操作元素拷贝的方式，
 * 在 xstd_vector_t 对象指定位置上安放新元素。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，
 * 引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xiter_pos : 安放节点的位置。
 * @param [in    ] xvct_elem : 节点所存储的元素。
 * 
 * @return xvct_iter_t : 安放后的节点对应的迭代器位置。
 */
xvct_iter_t std_vector_emplace(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos,
                xvct_elem_t xvct_elem)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_pos));
    XASSERT(XVCT_NULL != xvct_elem);

    xvct_iter_t xiter_npos = vector_unoccupy(xvct_this, xiter_pos, 1);

    XVCT_ALMOVE(xvct_this, XVCT_ITER_ELEM(xiter_npos), xvct_elem);

    return xiter_npos;
}

/**********************************************************/
/**
 * @brief 在 xstd_vector_t 对象指定位置上插入多个同值元素。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xiter_pos : 插入的位置。
 * @param [in    ] xst_count : 插入的节点元素数量。
 * @param [in    ] xvct_elem : 插入的同值元素。
 * 
 * @return xvct_iter_t : 插入后对应的起始节点迭代器位置。
 */
xvct_iter_t std_vector_insert_n(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos,
                xvct_size_t xst_count,
                xvct_elem_t xvct_elem)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_pos));
    XASSERT((0 == xst_count) || (XVCT_NULL != xvct_elem));

    xvct_iter_t xiter_npos = vector_unoccupy(xvct_this, xiter_pos, xst_count);
    xvct_iter_t xiter_trav = xiter_npos;

    while (xst_count-- > 0)
    {
        XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(xiter_trav), xvct_elem);
        XVCT_ITER_NEXT(xvct_this, xiter_trav);
    }

    return xiter_npos;
}

/**********************************************************/
/**
 * @brief 
 * 在 xstd_vector_t 对象指定位置上，插入外部
 * 区段 [ xiter_first, xiter_last ) 的节点元素。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_pos   : 插入的位置。
 * @param [in    ] xiter_first : 待插入区段的节点起始地址。
 * @param [in    ] xiter_last  : 待插入区段的节点结束地址。
 * 
 * @return xvct_iter_t : 返回插入后对应的区段起始节点位置。
 */
xvct_iter_t std_vector_insert_range(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos,
                xvct_iter_t xiter_first,
                xvct_iter_t xiter_last)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_pos));
    XASSERT(XVCT_NULL != xiter_first);
    XASSERT(XVCT_NULL != xiter_last);
    XASSERT(xiter_first <= xiter_last);
    XASSERT(XVCT_ITER_OUTER(xvct_this, xiter_first));
    XASSERT(XVCT_ITER_OUTER(xvct_this, xiter_last));

    xvct_size_t xst_count = XVCT_ITER_DIST(xvct_this, xiter_first, xiter_last);

    xvct_iter_t xiter_npos = vector_unoccupy(xvct_this, xiter_pos, xst_count);
    xvct_iter_t xiter_trav = xiter_npos;

    while (xiter_first != xiter_last)
    {
        XVCT_ALFROM(
            xvct_this, XVCT_ITER_ELEM(xiter_trav), XVCT_ITER_ELEM(xiter_first));

        XVCT_ITER_NEXT(xvct_this, xiter_trav );
        XVCT_ITER_NEXT(xvct_this, xiter_first);
    }

    return xiter_npos;
}

/**********************************************************/
/**
 * @brief 删除 xstd_vector_t 对象指定位置上的元素。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xiter_pos : 指定删除操作的节点位置。
 * 
 * @return xvct_iter_t : 返回删除操作后的后继节点位置（迭代器）。
 */
xvct_iter_t std_vector_erase(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(!XVCT_EMPTY(xvct_this));
    XASSERT(XVCT_ITER_HIT(xvct_this, xiter_pos));

    XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(xiter_pos));

    vector_move(
        xvct_this,
        xiter_pos,
        XVCT_ITER_OFFS(xvct_this, xiter_pos, 1),
        XVCT_ITER_END(xvct_this));
    XVCT_ITER_PREV(xvct_this, XVCT_ITER_END(xvct_this));

    return xiter_pos;
}

/**********************************************************/
/**
 * @brief 删除 xstd_vector_t 对象指定区域的节点元素。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_first : 删除操作的区域起始节点位置。
 * @param [in    ] xiter_last  : 删除操作的区域结束节点位置。
 * 
 * @return xvct_iter_t : 返回删除操作后的后继节点位置（迭代器）。
 */
xvct_iter_t std_vector_erase_range(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_first,
                xvct_iter_t xiter_last)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_first));
    XASSERT(XVCT_ITER_VALID(xvct_this, xiter_last));
    XASSERT(xiter_first <= xiter_last);

    vector_erase_range(xvct_this, xiter_first, xiter_last);

    return xiter_first;
}

/**********************************************************/
/**
 * @brief 向 xstd_vector_t 对象压入新的节点元素。
 */
xvct_void_t std_vector_push_back(
                xvct_this_t xvct_this,
                xvct_elem_t xvct_elem)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_NULL != xvct_elem);

    vector_expand(xvct_this, 1);

    XVCT_ALFROM(xvct_this, XVCT_ITER_ELEM(XVCT_ITER_END(xvct_this)), xvct_elem);
    XVCT_ITER_NEXT(xvct_this, XVCT_ITER_END(xvct_this));
}

/**********************************************************/
/**
 * @brief 以右值 move 方式，向 xstd_vector_t 对象压入新的节点元素。
 */
xvct_void_t std_vector_push_mback(
                xvct_this_t xvct_this,
                xvct_elem_t xvct_elem)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_NULL != xvct_elem);

    vector_expand(xvct_this, 1);

    XVCT_ALMOVE(xvct_this, XVCT_ITER_ELEM(XVCT_ITER_END(xvct_this)), xvct_elem);
    XVCT_ITER_NEXT(xvct_this, XVCT_ITER_END(xvct_this));
}

/**********************************************************/
/**
 * @brief 弹出 xstd_vector_t 对象的末端节点元素。
 */
xvct_void_t std_vector_pop_back(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(!XVCT_EMPTY(xvct_this));

    XVCT_ALDEST(xvct_this, XVCT_ITER_ELEM(XVCT_ITER_RBEGIN(xvct_this)));
    XVCT_ITER_PREV(xvct_this, XVCT_ITER_END(xvct_this));
}

/**********************************************************/
/**
 * @brief 
 * 调整 xstd_vector_t 对象当前容纳的节点元素数量。
 * 若调整的数量值大于当前数量（即扩容），则新增的节点元素，
 * 可使用 指定元素值 进行填充。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xvct_size : 调整的目标数量。
 * @param [in    ] xvct_elem : 扩容时使用的元素值。
 */
xvct_void_t std_vector_resize(
                xvct_this_t xvct_this,
                xvct_size_t xvct_size,
                xvct_elem_t xvct_elem)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(xvct_size <= XVCT_MAX_SIZE(xvct_this));
    XASSERT((0 == xvct_size) || (XVCT_NULL != xvct_elem));

    xvct_size_t xst_vsize = XVCT_SIZE(xvct_this);

    if (xvct_size > XVCT_CAPACITY(xvct_this))
    {
        vector_modify_capacity(xvct_this, xvct_size);
        vector_append(xvct_this, xvct_size - xst_vsize, xvct_elem);
    }
    else if (xvct_size > xst_vsize)
    {
        vector_append(xvct_this, xvct_size - xst_vsize, xvct_elem);
    }
    else if (xst_vsize > xvct_size)
    {
        vector_erase_range(
            xvct_this,
            XVCT_ITER_OFFS(xvct_this, XVCT_ITER_BEGIN(xvct_this), xvct_size),
            XVCT_ITER_END(xvct_this));
    }
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象指定索引位置对应的迭代器。
 * 
 * @param [in ] xvct_this : xstd_vector_t 对象。
 * @param [in ] xvct_vpos : 索引位置。
 * 
 * @return xvct_iter_t : 索引位置对应的迭代器。
 */
xvct_iter_t std_vector_iter(xvct_this_t xvct_this, xvct_size_t xvct_vpos)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(xvct_vpos <= XVCT_SIZE(xvct_this));
    return XVCT_ITER_OFFS(xvct_this, XVCT_ITER_BEGIN(xvct_this), xvct_vpos);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的起始节点 迭代器 位置。
 */
xvct_iter_t std_vector_begin(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_ITER_BEGIN(xvct_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的结束节点 迭代器 位置。
 */
xvct_iter_t std_vector_end(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_ITER_END(xvct_this);
}

/**********************************************************/
/**
 * @brief 对 xstd_vector_t 对象的迭代器进行前移一个节点位置。
 */
xvct_iter_t std_vector_next(xvct_this_t xvct_this, xvct_iter_t xiter_trav)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_HIT(xvct_this, xiter_trav));
    return XVCT_ITER_NEXT(xvct_this, xiter_trav);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的反向起始节点 迭代器 位置。
 */
xvct_iter_t std_vector_rbegin(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_ITER_RBEGIN(xvct_this);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的反向结束节点 迭代器 位置。
 */
xvct_iter_t std_vector_rend(xvct_this_t xvct_this)
{
    XASSERT(XVCT_NULL != xvct_this);
    return XVCT_ITER_REND(xvct_this);
}

/**********************************************************/
/**
 * @brief 对 xstd_vector_t 对象的迭代器反向进行前移一个节点位置。
 */
xvct_iter_t std_vector_rnext(xvct_this_t xvct_this, xvct_iter_t xiter_trav)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_HIT(xvct_this, xiter_trav));
    return XVCT_ITER_PREV(xvct_this, xiter_trav);
}

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的迭代器对应存储的元素值。
 */
xvct_elem_t std_vector_elem(xvct_this_t xvct_this, xvct_iter_t xiter_trav)
{
    XASSERT(XVCT_NULL != xvct_this);
    XASSERT(XVCT_ITER_HIT(xvct_this, xiter_trav));
    return XVCT_ITER_ELEM(xiter_trav);
}

////////////////////////////////////////////////////////////////////////////////

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__

////////////////////////////////////////////////////////////////////////////////
